/**
 * 
 */
package com.zznode.client.wlanpolling.model;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.xpath.XPathConstants;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.zznode.client.wlanpolling.WLanContext;
import com.zznode.client.wlanpolling.service.net.EnumHttpMethod;
import com.zznode.client.wlanpolling.service.net.HttpCallback;
import com.zznode.client.wlanpolling.service.net.HttpException;
import com.zznode.client.wlanpolling.service.net.HttpExecutorFactory;
import com.zznode.client.wlanpolling.service.net.HttpGetExecutor;
import com.zznode.client.wlanpolling.service.net.HttpParam;
import com.zznode.client.wlanpolling.service.xml.XmlXPathAdaptor;
import com.zznode.client.wlanpolling.utils.WLanPollingUtils;

/**
 * @author Pink
 * 
 */
public class NeighbouringAPManager implements HttpCallback {
	private static NeighbouringAPManager neighbouringAPManager;
	private double lontitue = 0, latitude = 0;
	
	private List<NearbyApInfo> nearbyApInfos1 = Collections.synchronizedList(new ArrayList<NearbyApInfo>());
	private List<NearbyApInfo> nearbyApInfos5 = Collections.synchronizedList(new ArrayList<NearbyApInfo>());
	private List<NearbyApInfo> nearbyApInfos10 = Collections.synchronizedList(new ArrayList<NearbyApInfo>());
	
	private static WLanContext context;
	
	private List<LoadDataFromNetworkCompleted> listenerDataLoadCompleted = new ArrayList<LoadDataFromNetworkCompleted>();
	
	public synchronized static NeighbouringAPManager getNeighbouringAPManager() {
		if (neighbouringAPManager == null) {
			neighbouringAPManager = new NeighbouringAPManager();
		}
		return neighbouringAPManager;
	}

	public static void setContext(WLanContext context) {
		NeighbouringAPManager.context = context;
	}

	public void registListener(LoadDataFromNetworkCompleted loadDataFromNetworkCompleted) {
		if(listenerDataLoadCompleted.contains(loadDataFromNetworkCompleted))
			return;
		listenerDataLoadCompleted.add(loadDataFromNetworkCompleted);
	}
	
	public void unRegistListener(LoadDataFromNetworkCompleted loadDataFromNetworkCompleted) {
		listenerDataLoadCompleted.remove(loadDataFromNetworkCompleted);
	}
	
	public void loadDataFromNetwork(double lontitue, double latitude) {
		if (lontitue != this.lontitue || latitude != this.latitude) {
			HttpGetExecutor executor = (HttpGetExecutor) HttpExecutorFactory
					.createHttpExecutor(EnumHttpMethod.GET);

			executor.addParam(new HttpParam("lontitue", lontitue + ""));
			executor.addParam(new HttpParam("latitude", latitude + ""));
			executor.addParam(new HttpParam("UID", context.getUid()));

			executor.setUrl(WLanPollingUtils.getHotspotinfoByLonLatURL());
			executor.asyncExecute(this, 0);
		} else {
			notifyDataLoadCompleted(null);
		}
	}
	
	private void notifyDataLoadCompleted(Exception e) {
		for(LoadDataFromNetworkCompleted listener : listenerDataLoadCompleted) {
			listener.onCompleted(e);
		}
	}

	@Override
	public void onReceiveData(byte[] data, HttpException exp, int tag) {
		try {
			
			nearbyApInfos1.clear();
			nearbyApInfos5.clear();
			nearbyApInfos10.clear();
			
			XmlXPathAdaptor xPath = new XmlXPathAdaptor(
					new ByteArrayInputStream(data));

			NodeList hotinfos = (NodeList) xPath.evaluate("/NODE/HOTINFO ",
					XPathConstants.NODESET);
			for (int i = 0; i < hotinfos.getLength(); i++) {
				Node hotinfoNode = hotinfos.item(i);
				String DISTANCE = hotinfoNode.getAttributes().getNamedItem("DISTANCE").getNodeValue();
				
				NodeList hots = hotinfoNode.getChildNodes();
				for (int j = 0; j < hots.getLength(); j++) {
					Node hot = hots.item(j);
					NearbyApInfo apInfo = new NearbyApInfo();

					apInfo.ADDRESS = hot.getAttributes()
							.getNamedItem("ADDRESS").getNodeValue();
					apInfo.DISTANCE = hot.getAttributes()
							.getNamedItem("DISTANCE").getNodeValue();
					apInfo.ID = hot.getAttributes().getNamedItem("ID")
							.getNodeValue();
					apInfo.LAT = hot.getAttributes().getNamedItem("LAT")
							.getNodeValue();
					apInfo.LON = hot.getAttributes().getNamedItem("LON")
							.getNodeValue();
					apInfo.NAME = hot.getAttributes().getNamedItem("NAME")
							.getNodeValue();
					apInfo.TYPE = hot.getAttributes().getNamedItem("TYPE")
							.getNodeValue();
					
					if(DISTANCE.equals("1")) {
						//1公里
						nearbyApInfos1.add(apInfo);
					} else if(DISTANCE.equals("5")) {
						//5公里
						nearbyApInfos5.add(apInfo);
					} else if(DISTANCE.equals("10")) {
						//10公里
						nearbyApInfos10.add(apInfo);
					}
				}
			}
		} catch (final Exception e) {
			notifyDataLoadCompleted(e);
			return;
		}
		
		notifyDataLoadCompleted(null);
	}

	public List<NearbyApInfo> getNearbyApInfos1() {
		return nearbyApInfos1;
	}

	public List<NearbyApInfo> getNearbyApInfos5() {
		return nearbyApInfos5;
	}

	public List<NearbyApInfo> getNearbyApInfos10() {
		return nearbyApInfos10;
	}	
}
